package service

import (
	"database/sql"
	"errors"
	"fmt"
	"gf-start-kit/library/base"
	"gf-start-kit/library/guid"
	"gf-start-kit/plugins/job/lib/jcron"
	"gf-start-kit/plugins/job/model/job"
	"github.com/gogf/gf/frame/g"
)

type JobService struct {
}
type Job struct {
	Name       string `p:"name"       json:"name" v:"required#任务名称不能为空"`          //
	Expression string `p:"expression" json:"expression" v:"required#cron表达式不能为空"` //
	FunName    string `p:"fun_name"   json:"fun_name" v:"required#cron表达式不能为空"`   // 方法名
	Type       string `p:"type"       json:"type" v:"required#任务类型不能为空"`          // 类型 正常系统方法还是url请求
	Url        string `p:"url"        json:"url"`                                 // url请求路径
	Param      string `p:"param"      json:"param"`                               //
	Times      int    `p:"times"      json:"times" v:"required#执行次数不能为空"`         // 执行次数 -1为循环执行
	Status     int    `p:"status"     json:"status"`                              // 0正常1禁用
}
type AddReq struct {
	ID int64 `json:"id"`
	Job
}
type EditReq struct {
	ID int64 `json:"id" v:"required|min-length:17#id不能为空|id不能为空"`
	Job
}

func (s *JobService) List(form *base.Form) ([]*job.Entity, error) {
	where := " 1 = 1 "
	var params []interface{}
	if !g.IsEmpty(form.Params) {
		if !g.IsEmpty(form.Params["nickname"]) {
			where += " and nickname like ? "
			params = append(params, "%"+form.Params["nickname"]+"%")
		}
	}
	return job.Model.Order(form.OrderBy).FindAll(where, params)
}
func (s *JobService) Page(form *base.Form) ([]job.Entity, error) {
	where := " 1 = 1 "
	var resData []job.Entity
	var params []interface{}
	if !g.IsEmpty(form.Params) {
		if !g.IsEmpty(form.Params["nickname"]) {
			where += " and nickname like ? "
			params = append(params, "%"+form.Params["nickname"]+"%")
		}
	}
	num, err := job.Model.As("t").FindCount(where, params)
	form.Total = num
	if err != nil {
		return resData, err
	}
	err = job.Model.Where(where, params).Order(form.OrderBy).Page(form.Page, form.PageSize).M.Structs(&resData)
	if err != nil {
		return resData, err
	}
	return resData, nil
}

func (s *JobService) Remove(id int64) (interface{}, error) {
	if id <= 0 {
		return new(job.Entity), errors.New("参数不合法")
	}
	return job.Model.Delete(" id = ?", id)
}

func (s *JobService) Get(id int64) (*job.Entity, error) {
	if id <= 0 {
		return new(job.Entity), errors.New("参数不合法")
	}
	return job.Model.FindOne(" id = ?", id)
}
func (s *JobService) Exist(name string, id ...int64) bool {
	m := job.Model
	m = m.Where(" name = ?", name)
	if len(id) > 0 {
		m = m.Where(" id <> ?", id[0])
	}
	c, _ := m.Count()
	return c > 0
}

func (s *JobService) Save(req AddReq) (sql.Result, error) {
	if !jcron.HasFun(req.FunName) {
		return nil, errors.New(fmt.Sprintf("[%s]方法名未注册", req.FunName))
	}
	if s.Exist(req.Name) {
		return nil, errors.New(fmt.Sprintf("[%s]任务名已存在", req.Name))
	}
	req.ID = guid.NewUUID()
	return job.Save(req)
}
func (s *JobService) Update(req EditReq) (sql.Result, error) {
	if req.ID <= 0 {
		return nil, errors.New("ID不能为空111")
	}
	if !jcron.HasFun(req.FunName) {
		return nil, errors.New(fmt.Sprintf("[%s]方法名未注册", req.FunName))
	}
	if s.Exist(req.Name, req.ID) {
		return nil, errors.New(fmt.Sprintf("[%s]任务名已存在", req.Name))
	}
	return job.Model.Data(req).Where(job.Columns.Id, req.ID).Update()
}

func (s *JobService) Start(Id int64) error {
	ent, _ := s.Get(Id)
	if g.IsEmpty(ent) {
		return errors.New("未找到任务")
	}
	if !jcron.HasFun(ent.FunName) {
		return errors.New(fmt.Sprintf("%s方法名未注册", ent.FunName))
	}
	return jcron.Start(ent)
}

func (s *JobService) Stop(Id int64) error {
	ent, _ := s.Get(Id)
	if g.IsEmpty(ent) {
		return errors.New("未找到任务")
	}
	if !jcron.HasFun(ent.FunName) {
		return errors.New("方法名没注册")
	}
	return jcron.Stop(ent)
}
